// Copyright 2022 Huawei Cloud Computing Technology Co., Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "CaeVideoPipeDataHandleThread.h"
#include "../cae_agent/CaeSocketAgent.h"
#include "../cae_service/CaeEngineControl.h"
#include "../cae_service/CaeParamStorage.h"

CaeVideoPipeDataHandleThread::CaeVideoPipeDataHandleThread(CaeDataPipe* pipe)
{
    m_threadStatus = CAE_THREAD_STATUS_NEW;
    m_videoData = pipe;
}

CaeVideoPipeDataHandleThread::~CaeVideoPipeDataHandleThread()
{
    m_videoData->ClearPipeData();
    m_threadStatus = CAE_THREAD_STATUS_EXIT;
}

void CaeVideoPipeDataHandleThread::Run()
{
    char threadName[] = "VideoPipeHandle";
    prctl(PR_SET_NAME, threadName);
    LOGI("CaeVideoPipeDataHandleThread run.");

    if (m_videoData == nullptr) {
        LOGE("Failed to run caeVideoPipeDataHandleThread, dataPipe is null.");
        return;
    }

    while (m_threadStatus == CAE_THREAD_STATUS_RUNNING) {
        if (CaeEngineControl::GetInstance().m_changeOrientation) {
            uint32_t payloadSize = sizeof(uint8_t);
            uint8_t *tmpBuff;
            tmpBuff = (uint8_t *)malloc(payloadSize + sizeof(STREAM_MSG_HEAD));
            if (tmpBuff == nullptr) {
                LOGE("Failed to malloc tmpBuff.");
                continue;
            }
            StreamMsgHead msgHead{};
            uint8_t msgType = CAE_MSG_ORIENTATION;
            msgHead.type = msgType;
            msgHead.magicWord = CAE_STREAM_DELIMITER_MAGICWORD;
            msgHead.checksum = (uint8_t)GET_CAE_CHECKSUM(msgType);
            msgHead.SetPayloadSize(payloadSize);
            uint8_t orientation = CaeEngineControl::GetInstance().m_orientation;
            if (memcpy_s(tmpBuff, sizeof(STREAM_MSG_HEAD), &msgHead, sizeof(STREAM_MSG_HEAD)) != EOK) {
                LOGE("Failed to memcpy msg head to tmpBuff.");
            }
            if (EOK != memcpy_s(tmpBuff + sizeof(STREAM_MSG_HEAD), payloadSize,
                                (const void *)&orientation, payloadSize) != EOK) {
                LOGE("Failed to memcpy msg head to tmpBuff.");
            }

            int ret = CaeSocketAgent::GetInstance().Send(tmpBuff, sizeof(STREAM_MSG_HEAD) + 1);
            if (ret > 0) {
                LOGI("Send video orientation buffer success, buffer: %d, ret: %d", orientation, ret);
                CaeEngineControl::GetInstance().m_changeOrientation = false;
            }
            free(tmpBuff);
        }
        CaePipeData *pipeData = m_videoData->GetPipeData();
        if (pipeData != nullptr && pipeData->GetLen() > 0) {
            int ret = CaeSocketAgent::GetInstance().Send((void *) pipeData->GetBuffer(),
                                                         pipeData->GetLen());
            if (ret < 0) {
                LOGE("Failed to send pipeData, ret is %d.", ret);
            }
            delete pipeData;
            pipeData = nullptr;
        }
        usleep(100);
    }
    m_threadStatus = CAE_THREAD_STATUS_EXIT;
    LOGI("CaeVideoPipeDataHandleThread exit.");
}